package server.network;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;


import common.Command;
import common.Log;
import common.TreeModelExplorer;

public class Server_Command extends Thread{

	private Socket m_client;
	private Server m_serveur;
	private String m_client_id;
	private BufferedWriter m_writer;
	private BufferedReader m_reader;
	private Server_Reception m_reception;


	public Server_Command(Socket client, Server serveur) {
		m_client = client;
		m_serveur = serveur;
		try{
			m_writer = new BufferedWriter(new OutputStreamWriter(m_client.getOutputStream()));
			m_reader = new BufferedReader(new InputStreamReader(m_client.getInputStream()));
			start();
		} catch(IOException e){
			e.printStackTrace();
		}
	}

	public void run() {
		String commande = null;
		while(true){
			try{
				commande = m_reader.readLine();
				if(commande.contains(Command.PSEUDO) && commande.contains(Command.PASSWORD)){
					
					String value[] = commande.split("<>");
					String datas_id[] = value[0].split("/]");
					String datas_pass[] = value[1].split("/]");
					String client_id = datas_id[1];
					String client_pass = datas_pass[1];
					if(server.auth.Server_Auth.get_authentification(client_id, client_pass)){
						m_writer.write(Command.CONNEXION_ACCEPTED);
						m_writer.newLine();
						m_writer.flush();
						m_client_id = client_id;
						Log.write_log(m_serveur.get_racine_path(), "Connexion d'un nouveau client", "Client id["+m_client_id+"] vient de se connecter...");
					}else{
						m_writer.write(Command.CONNEXION_REFUSED);
						m_writer.newLine();
						m_writer.flush();
					}
				}
				if(commande.contains(Command.SERVER_TREE)){
					send_tree_model();
				}
				if(commande.contains(Command.SYNCHRO_FILE)){
					String c[] = commande.split("<>");
					String c1[] = c[0].split("/]");
					String file_path = c1[1];
					String c2[] = c[1].split("/]");
					String file_date = c2[1];
					String c3[] = c[2].split("/]");
					String file_size = c3[1];
					String file_dest = "null";
					if(commande.contains(Command.FILE_DEST)){
						String c4[] = c[3].split("/]");
						file_dest = c4[1].substring(1);
					}
					File f_client = new File(file_path);
					File f_serveur = new File(m_serveur.get_racine_path()+file_dest+"/"+f_client.getName());
					boolean can_be_send = false;
					if(!file_existing(f_serveur) || !compare_file_date(f_serveur, Long.parseLong(file_date)) || !compare_file_size(f_serveur, Long.parseLong(file_size)))
						can_be_send = true;
					if(can_be_send){
						if(m_reception == null){
							m_reception = new Server_Reception(9002, m_serveur, this);
							m_reception.start();
						}
						m_writer.write(Command.SYNCHRO_FILE_READY+file_path+"<>"+Command.FILE_DEST+file_dest);
						m_writer.newLine();
						m_writer.flush();
					}else{
						Log.write_log(m_serveur.get_racine_path(), "Erreur copie de fichier", "Le fichier "+file_path+" n'a pas été copié");
					}
				}
				if(commande.contains(Command.CREATE_DIR)){
					String value[] = commande.split("/]");
					File f = new File(m_serveur.get_racine_path()+value[1].substring(1));
					if(f.exists())
					{
						Log.write_log(m_serveur.get_racine_path(), "Dossier non créé", f.getName()+" existe déjà");
						//m_writer.write(Command.DIR_CREATED);
					}
					else if(f.mkdir())
					{
						Log.write_log(m_serveur.get_racine_path(), "Dossier créé", f.getName()+" vient d'être créé");
						//m_writer.write(Command.DIR_CREATED);
					}
					else
					{
						Log.write_log(m_serveur.get_racine_path(), "Erreur création dossier", "Echec lors de la création du dossier "+f.getName());
						//m_writer.write(Command.DIR_NOT_CREATED);
					}
					send_tree_model();
				}
				if(commande.contains(Command.FERMETURE_CLIENT)){
					if(m_serveur.close_server()){
						Log.write_log(m_serveur.get_racine_path(), "Deconnexion du client", "Client id["+m_client_id+"] vient de se deconnecter...");
						m_writer.write(Command.FERMETURE_SERVEUR);
						m_writer.newLine();
						m_writer.flush();
					}
					System.exit(0);
				}
			}catch(Exception e){
				e.printStackTrace();
				m_serveur.close_server();
				System.exit(0);
			}
		}
	}

	/**
	 * Compare la date entre f1 et f2 : si f1 est plus récent, alors on retourne true; false dans les autres cas.
	 * @param f1
	 * @param f2
	 * @return boolean
	 */
	public boolean compare_file_date(File f1, long lastModifiedDate){
		if(f1.lastModified() > lastModifiedDate)
			return true;
		return false;
	}

	/**
	 * Compare la taille des fichiers f1 et f2 : si f1 est plus grand que f2, on retourne true, false dans les autres cas.
	 * @param f1
	 * @param f2
	 * @return boolean
	 */
	public boolean compare_file_size(File f1, long length ){
		if(f1.length() > length)
			return true;
		return false;
	}

	/**
	 * On vérifie si le fichier ou dossier existe : on retourne true dans le cas positif.
	 * @param f
	 * @return boolean
	 */
	public boolean file_existing(File f){
		if(f.exists())
			return true;
		return false;
	}
	
	/**
	 * Envoi l'arborescence locale du serveur
	 */
	public void send_tree_model() {
		try {
			m_writer.write(Command.SERVER_TREE);
			m_writer.newLine();
			m_writer.flush();
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			TreeModelExplorer _tree = new TreeModelExplorer(new File(m_serveur.get_racine_path()));
			ObjectOutputStream oos = new ObjectOutputStream(m_client.getOutputStream());
			oos.writeObject(_tree);
			oos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


}
